import json
import random
import datetime
from loguru import logger
from flask_cors import cross_origin
from flask import Blueprint, request, make_response
from flask_login import login_required, logout_user, confirm_login
from api import login_manager
from api.api_utils import catch_api_exception
from api.items import user_api_status_msg, ApiResponseError
from api.datas.data_api import *
from utils import get_uuid
from blockchain import *

user_bp = Blueprint("user_api", __name__)


@user_bp.route("/register", methods=["GET", "POST"])
@cross_origin(supports_credentials=True)
@catch_api_exception()
def register():
    request_params = request.json or request.args
    mobile = request_params.get('mobile')
    password = request_params.get('password')
    username = request_params.get('username')
    data = {
        'password': password,
        'username': username,
        'mobile': mobile,
        'user_id': get_uuid(),
        'is_admin': 0,
        'is_valid': 0,
        'go_valid': 0,
        'money': 0,
        'use_money': 0,
        'free_money': 0,
        'score': 70,
        'valid_infos': '',
        'valid_files': '',
        'create_time': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    }
    if get_user({'mobile': mobile}):
        logger.info(mobile + '已注册')
    else:
        insert_user(data)
        logger.info(mobile + '注册成功')
    if '_id' in data:
        del data['_id']
    return data


@user_bp.route("/login", methods=["GET", "POST"])
@cross_origin(supports_credentials=True)
@catch_api_exception()
def login():
    # request_params = request.json or request.args
    # token = request_params.get('data', {}).get('token') or request_params.get('token')
    # if token and User().get_user_by_id(token):
    #     user = User().get_user_by_id(token)
    #     if user and user.is_active:
    #         if login_user(user):
    #             result = {
    #                 'user_id': user.user_id,
    #                 'user_name': user.user_name,
    #                 'is_admin': user.is_admin,
    #                 'email': user.email
    #             }
    #             return result
    #     else:
    #         raise ApiResponseError(extra_msg=user_api_status_msg.login_error)
    request_params = request.json or request.args
    mobile = request_params.get('mobile')
    password = request_params.get('password')
    user = get_user({'mobile': mobile, 'password': password})
    if user:
        user = user[0]
        result = {
            'user_id': user['user_id'],
            'username': user['username'],
            'is_admin': user['is_admin'],
            'mobile': user['mobile'],
            'is_valid': user.get('is_valid', 0),
            'token': user['user_id'],
            'money': user.get('money', 0),
            'use_money': user.get('use_money', 0),
            'free_money': user.get('free_money', 0),
            'score': user.get('score', 70),
        }
        return result
    raise ApiResponseError(extra_msg=user_api_status_msg.login_error)


@user_bp.route("/money", methods=["GET", "POST"])
@cross_origin(supports_credentials=True)
@catch_api_exception()
def money():
    request_params = request.json or request.args
    user_id = request_params.get('user_id')
    mobile = request_params.get('mobile')
    if user_id:
        user = get_user({'user_id': user_id})
    else:
        user = get_user({'mobile': mobile})
    if user:
        user = user[0]
        result = {
            'user_id': user['user_id'],
            'username': user['username'],
            'is_admin': user['is_admin'],
            'mobile': user['mobile'],
            'is_valid': user.get('is_valid', 0),
            'token': user['user_id'],
            'money': user.get('money', 0),
            'use_money': user.get('use_money', 0),
            'free_money': user.get('free_money', 0),
            'score': user.get('score', 70),
        }
        return result
    raise ApiResponseError(extra_msg=user_api_status_msg.login_error)


@user_bp.route("/add_money", methods=["GET", "POST"])
@cross_origin(supports_credentials=True)
@catch_api_exception()
def add_money():
    request_params = request.json or request.args
    money = request_params.get('money', 0)
    user_id = request_params.get('user_id')
    mobile = request_params.get('mobile')
    chain_data = {'content': '资金托管:{},{},{}'.format(user_id, mobile, money),
                  'money': int(money),
                  'user_id': user_id,
                  'mobile': mobile,
                  'task_id': 0,
                  'extra': {}}
    user = get_user({'user_id': user_id})
    if not user:
        raise ApiResponseError(extra_msg=user_api_status_msg.login_error)
    else:
        inc = user[0].get('money', 0) + int(money)

    node_list = [STATIC_NODE1, STATIC_NODE2, STATIC_NODE3, STATIC_NODE4]
    rand_node = node_list.pop(random.choice([0, 1, 2, 3]))
    block = rand_node.mine(data=chain_data)
    rand_node.sync_data(block, node_list)
    update_user(user_id, {'money': inc})

    data = chain_data
    data['inc'] = inc
    write_news('用户尾号{}充值上链{}元'.format(mobile[-4:], money))
    return data


@user_bp.route("/user_block", methods=["GET", "POST"])
@cross_origin(supports_credentials=True)
@catch_api_exception()
def user_block():
    request_params = request.json or request.args
    user_id = request_params.get('user_id')
    mobile = request_params.get('mobile')
    if user_id:
        blocks = get_block_by_filters({'data.user_id': user_id})
    else:
        blocks = get_block_by_filters({'data.mobile': mobile})
    if blocks:
        return blocks
    raise ApiResponseError(extra_msg=user_api_status_msg.login_error)


@user_bp.route("/user_auth", methods=["GET", "POST"])
@cross_origin(supports_credentials=True)
@catch_api_exception()
def user_auth():
    request_params = request.json or request.args
    info = request_params.get('info')
    files = request_params.get('files')
    user_id = request_params.get('user_id')

    update_user(user_id, {'valid_infos': info, 'valid_files': files, 'is_valid': 2})
    return True


@user_bp.route("/user_auth_list", methods=["GET", "POST"])
@cross_origin(supports_credentials=True)
@catch_api_exception()
def user_auth_list():
    request_params = request.json or request.args
    info = request_params.get('info')
    files = request_params.get('files')
    user_id = request_params.get('user_id')

    update_user(user_id, {'valid_infos': info, 'valid_files': files, 'is_valid': 2})
    return True


@user_bp.route("/user_admin_list", methods=["GET", "POST"])
@cross_origin(supports_credentials=True)
@catch_api_exception()
def user_admin_list():
    user = get_user({"$or": [{"is_valid": 2}, {"is_valid": 1}]})
    return user


@user_bp.route("/user_admin_auth", methods=["GET", "POST"])
@cross_origin(supports_credentials=True)
@catch_api_exception()
def user_admin_auth():
    request_params = request.json or request.args
    user_id = request_params.get('user_id')
    user = get_user({'user_id': user_id})
    if not user:
        raise ApiResponseError(extra_msg=user_api_status_msg.login_error)

    update_user(user_id, {'is_valid': 1})

    return 'ok'


@user_bp.route("/reauth", methods=["GET", "POST"])
@login_required
@catch_api_exception()
def reauth():
    confirm_login()
    return 'reauth ok'


@user_bp.route("/logout")
@cross_origin(supports_credentials=True)
@login_required
def logout():
    logout_user()
    return 0


@login_manager.unauthorized_handler
def unauthorized_callback():
    result = make_response(json.dumps(user_api_status_msg.unauthorized, ensure_ascii=False))
    result.headers['Content-Type'] = 'application/json'
    return result

